<?php

namespace addons\litestore\model;

use think\Cache;
use think\Db;
use think\exception\PDOException;

/**
 * 购物车管理
 * Class Cart
 */
class CacheCart
{
    /* @var string $error 错误信息 */
    public $error = '';

    /* @var int $user_id 用户id */
    private $user_id;

    private $userInfo;

    /* @var array $cart 购物车列表 */
    private $cart = [];

    /* @var bool $clear 是否清空购物车 */
    private $clear = false;

    /**
     * 构造方法
     * Cart constructor.
     * @param $user_id
     */
    public function __construct($user_id)
    {
        $this->user_id = $user_id;
        $this->cart = Cache::get('cart_' . $this->user_id) ?: [];
        $this->userInfo = new User();
    }

    /**
     * 购物车列表
     */
    public function getList($user_id, $ids = null, $score = null)
    {
        // 商品列表
        $goodsList = [];
        #$goodsIds = array_unique(array_column($this->cart, 'goods_id'));
        $where = ['user_id' => $this->user_id];
        if ($ids)
            $where['goods_id'] = ['in', $ids];
        $goodsCart = Db::name('user_cart')->where($where)->select();
        $goodsIds = array_column($goodsCart, 'goods_id');

        foreach ((new Wxlitestoregoods)->getListByIds($goodsIds) as $goods) {
            $goodsList[$goods['goods_id']] = $goods;
        }
        // 当前用户收货城市id
        $defaultcity = Litestoreadress::getdefault($user_id);
        $cityId = $defaultcity ? $defaultcity['city_id'] : null;

        // 是否存在收货地址
        $exist_address = $defaultcity;
        // 商品是否在配送范围
        $intraRegion = true;
        // 购物车商品列表
        $cartList = [];
        #foreach ($this->cart as $key => $cart)
        foreach ($goodsCart as $key => $cart) {

            // 判断商品不存在则自动删除
            if (!isset($goodsList[$cart['goods_id']])) {
                $this->delete($cart['goods_id'], $cart['goods_sku_id']);
                continue;
            }
            /* @var Goods $goods */
            $goods = $goodsList[$cart['goods_id']];
            // 商品sku信息
            $goods['goods_sku_id'] = $cart['goods_sku_id'];
            // 商品sku不存在则自动删除
            if (!$goods['goods_sku'] = $goods->getGoodsSku($cart['goods_sku_id'])) {
                Db::name('user_cart')->where(['user_id' => $this->user_id, 'goods_id' => $cart['goods_id']])->delete();
                # $this->delete($cart['goods_id'], $cart['goods_sku_id']);
                continue;
            }
            $goods['show_error'] = 0;
            // 判断商品是否下架
            if ($goods['goods_status'] !== '10') {
                $goods['show_error'] = 1;
                $goods['show_error_text'] = '已下架';
                $this->setError('很抱歉，商品 [' . $goods['goods_name'] . '] 已下架');
            }
            // 判断商品库存
            if ($cart['goods_num'] > $goods['goods_sku']['stock_num']) {
                $goods['show_error'] = 2;
                $goods['show_error_text'] = '库存不足';
                $this->setError('很抱歉，商品 [' . $goods['goods_name'] . '] 库存不足');
            }
            // 商品单价
            $goods['goods_price'] = $goods['goods_sku']['goods_price'];
            // 商品总价
            $goods['total_num'] = $cart['goods_num'];
            $goods['total_price'] = $total_price = bcmul($goods['goods_price'], $cart['goods_num'], 2);
            // 商品总重量
            $goods['goods_total_weight'] = bcmul($goods['goods_sku']['goods_weight'], $cart['goods_num'], 2);
            // 验证用户收货地址是否存在运费规则中
            if ($intraRegion = $goods['freight']->checkAddress($cityId)) {
                $goods['express_price'] = $goods['freight']->calcTotalFee(
                    $cart['goods_num'], $goods['goods_total_weight'], $cityId);
            } else {
                //$goods['show_error'] = 3;
                //$goods['show_error_text'] = '收货区域无法配送';
                $exist_address && $this->setError("很抱歉，您的收货地址不在商品 [{$goods['goods_name']}] 的配送范围内");
            }
            $goodArr = $goods->toArray();
            $goodArr['checked'] = false;
            $cartList[] = $goodArr;
        }
        // 商品总金额
        $orderTotalPrice = array_sum(array_column($cartList, 'total_price'));
        // 所有商品的运费金额
        $allExpressPrice = array_column($cartList, 'express_price');
        // 订单总运费金额
        $expressPrice = $allExpressPrice ? Litestorefreight::freightRule($allExpressPrice) : 0.00;
        $user = $this->userInfo->find($user_id);
        $integralOff = Db::table('fa_config')->where('name', '=', 'integralOff')->value('value');
        $integral = Db::table('fa_config')->where('name', '=', 'integralTormb')->value('value');
        $lastArr = [
            'goods_list' => $cartList,                       // 商品列表
            'order_total_num' => 1,#$this->getTotalNum(),       // 商品总数量
            'order_total_price' => round($orderTotalPrice, 2),              // 商品总金额 (不含运费)
            'order_pay_price' => bcadd($orderTotalPrice, $expressPrice, 2),    // 实际支付金额
            'score' => $user->score,
            'address' => $defaultcity,  // 默认地址
            'exist_address' => $exist_address,      // 是否存在收货地址
            'express_price' => $expressPrice,       // 配送费用
            'intra_region' => $intraRegion,         // 当前用户收货城市是否存在配送规则中
            'has_error' => $this->hasError(),
            'error_msg' => $this->getError(),
            #获取积分
            'integralMsg' => "积分兑换比例为" . $integral . ":1",
            'integralOff' => $integralOff,
            'integral' => $integral
        ];
        if($score > 0 && $integralOff == 1){
            $lastArr['order_pay_price'] = bcsub(bcadd($orderTotalPrice, $expressPrice, 2) , $score/$integral ,2);
            $lastArr['pay_score'] = $score;
        }
        return $lastArr;
    }

    /**
     * 添加购物车
     * @param $goods_id
     * @param $goods_num
     * @param $goods_sku_id
     * @return bool
     * @throws \think\exception\DbException
     */
    public function add($goods_id, $goods_num, $goods_sku_id)
    {
        #判断是否已有
        $exist = Db::name('user_cart')->where(['user_id' => $this->user_id, 'goods_id' => $goods_id])->find();
        if ($exist) {
            Db::name('user_cart')->where(['user_id' => $this->user_id, 'goods_id' => $goods_id])->setInc('goods_num', 1);
            return true;
        }
        // 购物车商品索引
        $index = $goods_id . '_' . $goods_sku_id;
        // 商品信息
        $goods = Wxlitestoregoods::detail($goods_id);
        // 商品sku信息
        $goods['goods_sku'] = $goods->getGoodsSku($goods_sku_id);
        // 判断商品是否下架
        if ($goods['goods_status'] !== '10') {
            $this->setError('很抱歉，该商品已下架');
            return false;
        }
        // 判断商品库存
        #$cartGoodsNum = $goods_num + (isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] : 0);
        if ($goods_num > $goods['goods_sku']['stock_num']) {
            $this->setError('很抱歉，商品库存不足');
            return false;
        }
#         $cartGoodsNum = $goods_num + (isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] : 0);
#        if ($cartGoodsNum > $goods['goods_sku']['stock_num']) {
#            $this->setError('很抱歉，商品库存不足');
#            return false;
#        }
        $create_time = time();
        $data = compact('goods_id', 'goods_num', 'goods_sku_id', 'create_time');
        $data['user_id'] = $this->user_id;
        #原存储为文件缓存  改为 数据库存储

        $result = Db::name('user_cart')->insert($data);
        #if (empty($this->cart)) {
        #    $this->cart[$index] = $data;
        #    return true;
        #}
        if (!$result) {
            $this->error = "添加购物车失败";
            return true;
        }
        #isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] = $cartGoodsNum : $this->cart[$index] = $data;
        return true;
    }

    /**
     * 减少购物车中某商品数量
     * @param $goods_id
     * @param $goods_sku_id
     */
    public function sub($goods_id, $goods_sku_id)
    {
        Db::name('user_cart')->where(['user_id' => $this->user_id, 'goods_id' => $goods_id])->setDec('goods_num', 1);
        return true;
        #$index = $goods_id . '_' . $goods_sku_id;
        #$this->cart[$index]['goods_num'] > 1 && $this->cart[$index]['goods_num']--;
    }

    /**
     * 删除购物车中指定商品
     * @param $goods_id
     * @param $goods_sku_id
     */
    public function delete($goods_id, $goods_sku_id)
    {
        Db::name('user_cart')->where(['user_id' => $this->user_id, 'goods_id' => $goods_id])->delete();
        return true;
        #$index = $goods_id . '_' . $goods_sku_id;
        #unset($this->cart[$index]);
    }

    /**
     * 获取当前用户购物车商品总数量
     * @return int
     */
    public function getTotalNum()
    {
        #原 获取 购物车 数量
        #return array_sum(array_column($this->cart, 'goods_num'));
        $where['user_id'] = $this->user_id;
        return Db::name('user_cart')->where($where)->count();
    }

    /**
     * 析构方法
     * 将cart数据保存到缓存文件
     */
    public function __destruct()
    {
        $this->clear !== true && Cache::set('cart_' . $this->user_id, $this->cart, 86400 * 15);
    }

    /**
     * 清空当前用户购物车
     */
    public function clearAll()
    {
        $this->clear = true;
        Cache::rm('cart_' . $this->user_id);
    }

    /**
     * 设置错误信息
     * @param $error
     */
    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    /**
     * 是否存在错误
     * @return bool
     */
    private function hasError()
    {
        return !empty($this->error);
    }

    /**
     * 获取错误信息
     * @return string
     */
    public function getError()
    {
        return $this->error;
    }

}
